package io.jee.caisan.weixin.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import io.jee.alaska.util.Result;
import io.jee.caisan.weixin.domain.MpMenu;
import io.jee.caisan.weixin.repository.MpMenuRepository;
import io.jee.caisan.weixin.service.MpMenuService;
import io.jee.caisan.weixin.utils.EmojiUtils;
import io.jee.caisan.weixin.vo.MpMenuVo;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.menu.WxMpMenu;

@Service
@Transactional
public class MpMenuServiceImpl implements MpMenuService {

	@Resource
	private MpMenuRepository mpMenuRepository;

	@Resource
	private WxMpService wxService;
	
	@Override
	public List<MpMenuVo> findBySource(String source) {
		List<MpMenu> menus = mpMenuRepository.select().where("source", source).order().asc("level").asc("sort").end().list();
		return treeMenuList(menus);
	}
	
	private static List<MpMenuVo> treeMenuList(List<MpMenu> menus){
		List<MpMenuVo> vos = new ArrayList<>();
		for (MpMenu menu : menus) {
			if(menu.getParent() == null) {
				MpMenuVo vo = new MpMenuVo();
				BeanUtils.copyProperties(menu, vo);
				vos.add(vo);
				findChildren(menus, vo);
			}
		}
		return vos;
	}
	
	private static List<MpMenuVo> findChildren(List<MpMenu> menus, MpMenuVo vo){
		List<MpMenuVo> child = new ArrayList<>();
		for (MpMenu menu : menus) {
			if(menu.getParent() != null && menu.getParent().getId() == vo.getId()) {
				MpMenuVo menuVo = new MpMenuVo();
				BeanUtils.copyProperties(menu, menuVo);
				child.add(menuVo);
				findChildren(menus, menuVo);
			}
		}
		vo.setSubButtons(child);
		return child;
	}
	
	@Override
	public Result<?> asyncMenu() {
		try {
			mpMenuRepository.update().set("parent", null).where("source", MpMenu.SOURCE_REMOTE).end();
			mpMenuRepository.delete().where("source", MpMenu.SOURCE_REMOTE).end();
			WxMpMenu wxMpMenu = wxService.getMenuService().menuGet();
			if(wxMpMenu != null) {
				List<WxMenuButton> buttons = wxMpMenu.getMenu().getButtons();
				convertSaveMenus(buttons, null, 0, MpMenu.SOURCE_REMOTE);
			}
		} catch (WxErrorException e) {
			Result.error("微信菜单获取失败：" + e.getMessage());
			e.printStackTrace();
		}
		return Result.success();
	}

	private void convertSaveMenus(List<WxMenuButton> buttons, MpMenu parent, int level, String source) {
		int sort = 0;
		for (WxMenuButton button : buttons) {
			MpMenu menu = new MpMenu();
			menu.setAppId(button.getAppId());
			menu.setKey(button.getKey());
			menu.setMediaId(button.getMediaId());
			menu.setName(EmojiUtils.filterEmoji(button.getName()));
			menu.setPagePath(button.getPagePath());
			menu.setType(button.getType());
			menu.setUrl(button.getUrl());
			menu.setLevel(level);
			menu.setSort(sort);
			menu.setSource(source);
			menu.setParent(parent);
			mpMenuRepository.save(menu);
			sort++;
			if (button.getSubButtons().size() > 0) {
				level++;
				convertSaveMenus(button.getSubButtons(), menu, level, source);
			}
		}
	}

	@Override
	public Result<?> saveMenu(List<WxMenuButton> buttons) {
		mpMenuRepository.update().set("parent", null).where("source", MpMenu.SOURCE_LOCAL).end();
		mpMenuRepository.delete().where("source", MpMenu.SOURCE_LOCAL).end();
		convertSaveMenus(buttons, null, 0, MpMenu.SOURCE_LOCAL);
		return Result.success();
	}

	@Override
	public Result<?> publishMenu() {
		List<MpMenu> menus = mpMenuRepository.select().where("source", MpMenu.SOURCE_LOCAL).order().asc("level").asc("sort").end().list();
		if(menus == null) {
			return Result.error("没有任何菜单被创建");
		}
		List<MpMenuVo> list = treeMenuList(menus);
		WxMenu menu = new WxMenu();
		for (MpMenuVo vo : list) {
			WxMenuButton button = new WxMenuButton();
			button.setType(vo.getType());
			button.setName(vo.getName());
			button.setKey(vo.getKey());
			button.setUrl(vo.getUrl());
			button.setMediaId(vo.getMediaId());
			button.setAppId(vo.getAppId());
			button.setPagePath(vo.getPagePath());
			if(vo.getSubButtons() != null) {
				for (MpMenuVo mpMenuVo : vo.getSubButtons()) {
					WxMenuButton subButton = new WxMenuButton();
					subButton.setType(mpMenuVo.getType());
					subButton.setName(mpMenuVo.getName());
					subButton.setKey(mpMenuVo.getKey());
					subButton.setUrl(mpMenuVo.getUrl());
					subButton.setMediaId(mpMenuVo.getMediaId());
					subButton.setAppId(mpMenuVo.getAppId());
					subButton.setPagePath(mpMenuVo.getPagePath());
					button.getSubButtons().add(subButton);
				}
			}
			menu.getButtons().add(button);
		}
		try {
			wxService.getMenuService().menuCreate(menu);
		} catch (WxErrorException e) {
			e.printStackTrace();
			return Result.error("创建菜单失败！错误原因：" + e.getMessage());
		}
		return Result.success();
	}

	@Override
	public Result<?> deleteMenu() {
		try {
			wxService.getMenuService().menuDelete();
		} catch (WxErrorException e) {
			e.printStackTrace();
			return Result.error("删除菜单失败！错误原因：" + e.getMessage());
		}
		return Result.success();
	}
	

}
